import HistorySessionDTO from "./sdk/echatim/model/dto/HistorySessionDTO";
import EChatIMApis from "./sdk/echatim/core/apis/EChatIMApis";
import HistoryListSessionForm from "./sdk/echatim/model/form/HistoryListSessionForm";
import Logger from "./sdk/echatim/log/Logger";
import {HistorySessionStore} from "../model/store/HistorySessionStore";
import ChatsContentStore, {ChatsStore} from "../model/store/ChatsContentStore";
import {UserInfoStore} from "../model/store/UserInfoStore";
import {FriendToAddRoomStore} from "../model/store/FriendToAddRoomStore";
import {RoomListStore} from "../model/store/RoomListStore";
import {FriendListStore} from "../model/store/FriendListStore";
import Beans from "./sdk/echatim/common/utils";
import {IEChatIMSDKListener} from "./sdk/echatim/core/sdk/EChatIMSDK";
import UserBlackForbidListDTO from "./sdk/echatim/model/dto/UserBlackForbidListDTO";
import MessageReceiveDTO from "./sdk/echatim/model/dto/MessageReceiveDTO";
import UserFriendListDTO from "./sdk/echatim/model/dto/UserFriendListDTO";
import RoomListDTO from "./sdk/echatim/model/dto/RoomListDTO";
import UserListDTO from "./sdk/echatim/model/dto/UserListDTO";
import UserFriendListForm from "./sdk/echatim/model/form/UserFriendListForm";
import RoomListJoinForm from "./sdk/echatim/model/form/RoomListJoinForm";
import CommonListData from "../model/item/CommonListData";
import Toast from "../components/toast/Toast";
import NavigatorBar from "../components/navigator/NavigatorFactory";
import RoomAddForm from "./sdk/echatim/model/form/RoomAddForm";
import {SimpleDateFormat} from "./utils/SimpleDateFormat";


export type sessionListenerType = (list:Array<HistorySessionStore>)=>void
export type friendListenerType = (list:Array<FriendListStore>)=>void
export type roomListenerType = (list:Array<RoomListStore>)=>void
export type chatListenerType = (list:Array<ChatsStore>)=>void


export default class ShareStore {
    // windows 窗口 (chat:聊天, system:系统消息)
    public windowTab =  '';
    public online = 0;
    public avatarType = ''; // 修改头像的类型 (self:自己的头像; room = 讨论组的头像)
    public sessionTopList = ['添加好友','添加讨论组', '系统消息']; // 放置在会话列表的功能列表
    public sessionList:Array<HistorySessionStore> = []; // 会话列表
    public friendList:Array<FriendListStore> = []; // 好友列表
    public roomList:Array<RoomListStore> = []; // 讨论组列表
    public friendToAddRoomList:Array<FriendToAddRoomStore> = []; // 待添加到讨论组的朋友列表
    // public listExtraInfo = {}; // 会话列表, 好友列表, 讨论组列表 的补充信息
    public faces = new Array<any>(); // 表情gif
    // 系统消息
    public systemMessages = new Array<any>();
    // 用户信息
    public userInfo:UserInfoStore = new UserInfoStore();
    // 聊天正文
    public chatsContent:ChatsContentStore = new ChatsContentStore();
    // 发送的内容
    // public msgContent = {
    //     text: ''
    // };
    // 要添加的好友
    public friendAdd = {
        auid: ''
    };

    public showToast(msg:string){
        Toast.show(msg, Toast.LONG);
    }
    public showApiErrorToast(e) {
        console.trace(e);
        if (e instanceof Error) {
            this.showToast(e+'');
        } else if (e.errorMessage !== undefined) {
            this.showToast(e.errorMessage);
        }
    }

    public isSelectPersonTag(){
        return this.chatsContent.select === 'friend' || this.chatsContent.select === 'session';
    };

    public selectChartContent(category:string, data: CommonListData, roomOwner:string){
        this.windowTab = 'chat';
        this.chatsContent.select = category;
        this.chatsContent.selectId = data.id;
        this.chatsContent.friendInfo.auid = data.id;
        this.chatsContent.friendInfo.name = data.name;
        this.chatsContent.friendInfo.avatar = data.avatar;

        if (category === 'session') {
            this.chatsContent.select = 'session';
            this.chatsContent.selectId = data.id;
            this.chatsContent.friendInfo.auid = data.id;
            this.chatsContent.friendInfo.name = data.name;
            this.chatsContent.friendInfo.avatar = data.avatar;
        } else if (category === 'friend') {
            this.chatsContent.select = 'friend';
            this.chatsContent.selectId = data.id;
            this.chatsContent.friendInfo.auid = data.id;
            this.chatsContent.friendInfo.name = data.name;
            this.chatsContent.friendInfo.avatar = data.avatar;
            this.chatsContent.friendInfo.online = data.online;
        } else if (category === 'room') {
            this.chatsContent.select = 'room';
            this.chatsContent.selectId = data.id;
            this.chatsContent.roomInfo.rid = parseInt(data.id);
            this.chatsContent.roomInfo.name = data.name;
            this.chatsContent.roomInfo.avatar = data.avatar;
            if(roomOwner){
                this.chatsContent.roomInfo.owner = roomOwner;
            }
        }

        this.cleanUnReadMessage(category, this.chatsContent.selectId); // 清空消息未读数
    }

    cleanUnReadMessage(listType, key) {
        if(listType === 'session'){
            const target = globalStore.sessionList.filter(function (v) {
                return v.toTarget === key;
            });
            if(target.length > 0){
                target[0].unread = 0;
            }
            // notify data list
            globalStore.notifySessionUpdate();
        }
        else if(listType === 'room'){
            const target = globalStore.roomList.filter(function (v) {
                return v.rid === parseInt(key);
            });
            if(target.length > 0){
                target[0].unread = 0;
            }
            // notify data list
            // globalStore.notifyRoomUpdate();
        }
        // notify data list

    }
    incrementUnReadMessage(listType, key) {
        if(listType === 'session'){
            const target = globalStore.sessionList.filter(function (v) {
                return v.toTarget === key;
            });
            if(target.length > 0){
                target[0].unread += 1;
            }
            // notify data list
            globalStore.notifySessionUpdate();
        }
        else if(listType === 'room'){
            const target = globalStore.roomList.filter(function (v) {
                return v.rid === parseInt(key);
            });
            if(target.length > 0){
                target[0].unread = target[0].unread === undefined ? 1 : target[0].unread + 1;
            }
            // notify data list
            globalStore.notifyRoomUpdate();
        }

    }

    public sdkListener: IEChatIMSDKListener = new class implements IEChatIMSDKListener {
        onConnected(): void {
            globalStore.online = 1;
        }
        onDisConnected(): void {
            globalStore.online = 0;
        }
        onUserInfo(userInfo: UserListDTO) {
            globalStore.userInfo = userInfo;
        }
        onMessageReceive(message: MessageReceiveDTO) {
            if (message.way === 'P2P' || message.way === 'P2R') {
                if(message.way === 'P2P'){
                    globalStore.incrementUnReadMessage('session', message.fromUser); // 最近会话消息未读数+1
                }
                else if(message.way === 'P2R'){
                    globalStore.incrementUnReadMessage('room', message.toTarget); // 群消息未读数+1
                }
                if (globalStore.windowTab === 'chat') {
                    // 群: 不要显示自己发送的消息
                    if (message.fromUser === globalStore.userInfo.auid) {
                        return;
                    }
                    // 收到'P2P', 但打开了其它窗口
                    if (message.way === 'P2P') {
                        if (!globalStore.isSelectPersonTag() || globalStore.chatsContent.selectId !== message.fromUser)
                            return;
                    }
                    // 收到'P2R', 但打开了其它窗口
                    if (message.way === 'P2R') {
                        if (globalStore.isSelectPersonTag() || parseInt(globalStore.chatsContent.selectId) !== parseInt(message.toTarget))
                            return;
                        //  群最后一条消息的时间为当前时间
                        const targetRoom = globalStore.roomList.filter(function (v) {
                            return v.rid === parseInt(message.toTarget);
                        });
                        if(targetRoom.length > 0){
                            targetRoom[0].lastMsgTime = SimpleDateFormat.format(new Date(), 'yyyy-MM-dd hh:mm:ss');
                        }
                    }
                    // 加入刚刚收到的信息到聊天窗口
                    const chat = new ChatsStore();
                    chat.toMe = 1;
                    chat.body = message.body;
                    chat.createTime = new Date();
                    globalStore.chatsContent.chats.push(chat);

                    // send Broadcast
                    // this.scrollMessageContainerToBottom();
                }
            }
        }
        onEventReceive(event: any) {
            console.log("onEventReceive:" + Beans.json(event));
            if(event.eventType === 'CLIENT_ONLINE'){
                const jsonBody = Beans.bean(event.body);
                globalStore.sessionList.forEach(function (v) {
                    if(v.toTarget === jsonBody.auid){
                        v.online = jsonBody.online;
                    }
                });
                globalStore.friendList.forEach(function (v) {
                    if(v.auid === jsonBody.auid){
                        v.online = jsonBody.online;
                    }
                });
                if(globalStore.chatsContent.friendInfo.auid === jsonBody.auid){
                    globalStore.chatsContent.friendInfo.online = jsonBody.online;
                }

                globalStore.notifyFriendUpdate();
                // app.$forceUpdate();
            }
        }
        onSessionList(resp: Array<HistorySessionDTO>): void {
            globalStore.sessionList = resp.map((v)=>Beans.to(v));
            const targetAuids = globalStore.sessionList.map(function (v) {
                return v.toTarget;
            });
            globalStore.notifySessionUpdate();
            // 监听最近会话的在线状态
            EChatIMApis.addOnlineMonitor.call({auid:globalStore.userInfo.auid, targetAuids:targetAuids}).then((resp) => {
                // app.showToast("设置成功");
            }).catch((e) => {
                globalStore.showApiErrorToast(e);
                Logger.trace(e);
                // TODO: send broadcast
            })
        }
        onFriendList(resp: Array<UserFriendListDTO>): void {
            globalStore.friendList = resp.map((v)=>Beans.to(v));
            const targetAuids = globalStore.friendList.map(function (v) {
                return v.auid;
            });
            // 监听朋友的在线状态
            EChatIMApis.addOnlineMonitor.call({auid:globalStore.userInfo.auid, targetAuids:targetAuids}).then((resp) => {
                globalStore.showToast("设置在线监听成功");
            }).catch((e) => {
                globalStore.showApiErrorToast(e);
                Logger.trace(e);
                // TODO: send broadcast
            })
        }
        onBlacklistForbidList(list: Array<UserBlackForbidListDTO>): void {

        }
        onRoomList(resp: Array<RoomListDTO>): void {
            globalStore.roomList = resp.map((v)=>Beans.to(v));
        }
        onError(e: any): void {
            Logger.trace(e);
            globalStore.showApiErrorToast(e);
            // TODO: send broadcast
        }

    };



    //  ---------- components 监听/广播 ------------//
    private sessionListener:Array<sessionListenerType> = [];
    public notifySessionUpdate(){
        this.sessionListener.forEach((listener)=>{
            listener(this.sessionList);
        })
    }
    public addSessionListener(listener:sessionListenerType){
        this.sessionListener.push(listener);
    }
    public requestSessionUpdate(){
        const historyListSessionForm = new HistoryListSessionForm();
        historyListSessionForm.auid = this.userInfo.auid;
        historyListSessionForm.startTimestamp = 0;
        historyListSessionForm.endTimestamp = new Date().getTime();
        EChatIMApis.historyListSession.call(historyListSessionForm).then((response)=>{
            const sessions = (response.data as Array<HistorySessionStore>);
            const preSessionMapByTarget = Beans.toMapByKey(this.sessionList, 'toTarget');
            this.sessionList = sessions.map((v)=>Beans.replace( preSessionMapByTarget.hasOwnProperty(v.toTarget) ? preSessionMapByTarget[v.toTarget] : {}, v));
            this.notifySessionUpdate();
        }).catch((e)=>{
            Logger.trace(e);
        })
    }

    private friendListener:Array<friendListenerType> = [];
    public notifyFriendUpdate(){
        this.friendListener.forEach((listener)=>{
            listener(this.friendList);
        })
    }
    public addFriendListener(listener:friendListenerType){
        this.friendListener.push(listener);
    }
    public requestFriendUpdate(){
        const userFriendListForm = new UserFriendListForm();
        userFriendListForm.auid = this.userInfo.auid;
        EChatIMApis.listFriends.call(userFriendListForm).then((response)=>{
            const friends = (response.data as Array<UserFriendListDTO>);
            const preFriendMapByAuid = Beans.toMapByKey(this.friendList, 'auid');
            this.friendList = friends.map((v)=>Beans.replace( preFriendMapByAuid.hasOwnProperty(v.auid) ? preFriendMapByAuid[v.auid] : {}, v));
            this.notifyFriendUpdate();
        }).catch((e)=>{
            Logger.trace(e);
        })
    }

    private roomListener:Array<roomListenerType> = [];
    public notifyRoomUpdate(){
        this.roomListener.forEach((listener)=>{
            listener(this.roomList);
        })
    }
    public addRoomListener(listener:roomListenerType){
        this.roomListener.push(listener);
    }

    public requestRoomUpdate(){
        const roomListJoinForm = new RoomListJoinForm();
        roomListJoinForm.auid = this.userInfo.auid;
        EChatIMApis.listRoomJoin.call(roomListJoinForm).then((response)=>{
            const rooms = (response.data as Array<RoomListDTO>);
            const preRoomMapByRid = Beans.toMapByKey(this.roomList, 'rid');
            this.roomList = rooms.map((v)=>Beans.replace(preRoomMapByRid.hasOwnProperty(v.rid) ? preRoomMapByRid[v.rid] : {}, v));
            this.notifyRoomUpdate();
        }).catch((e)=>{
            Logger.trace(e);
        })
    }



    private chatListener:Array<chatListenerType> = [];
    public notifyChatUpdate(){
        this.chatListener.forEach((listener)=>{
            listener(this.chatsContent.chats);
        })
    }
    public addChatListener(listener:chatListenerType){
        this.chatListener.push(listener);
    }
    public requestChatUpdate(){
        // const userChatListForm = new UserChatListForm();
        // userChatListForm.auid = this.userInfo.auid;
        // EChatIMApis.listChats.call(userChatListForm).then((response)=>{
        //     const chats = (response.data as Array<UserChatListDTO>);
        //     const preChatMapByAuid = Beans.toMapByKey(this.chatList, 'auid');
        //     this.chatList = chats.map((v)=>Beans.replace( preChatMapByAuid.hasOwnProperty(v.auid) ? preChatMapByAuid[v.auid] : {}, v));
        //     this.notifyChatUpdate();
        // }).catch((e)=>{
        //     Logger.trace(e);
        // })
    }




    // ---------------- About page ------------//
    onModifySelfAvatarPressOk(){
        NavigatorBar.pop();
    }

    onAddFriendPressOk(){
        if(!globalStore.friendAdd.auid){
            globalStore.showToast('请输入好友auid');
            return;
        }
        const form = {
            auid: globalStore.userInfo.auid,
            targetAuid: globalStore.friendAdd.auid,
            type: 'ADD',
            alias: '',
            applyText: '我要加你好友了'
        };
        EChatIMApis.addFriend.call(form).then((resp) => {
            globalStore.showToast("添加好友成功.");
            // app.$bvModal.hide('add-friend-modal');
            NavigatorBar.pop();
            // 刷新好友列表
            EChatIMApis.listFriends.call({auid: globalStore.userInfo.auid, updatetime:0}).then((resp) => {
                globalStore.friendList = resp.data;
            }).catch((e) => {
                console.error(e);
            })
        }).catch((e) => {
            globalStore.showApiErrorToast(e);
        });
    }

    onModifyUserInfoPressOk(){
        EChatIMApis.userUpdate.call(Beans.to(globalStore.userInfo)).then((resp) => {
            globalStore.showToast("修改成功");
            NavigatorBar.pop();
        }).catch((e) => {
            globalStore.showApiErrorToast(e);
        })
    }


    onModifyFriendInfoPressOk(){
        EChatIMApis.modifyAlias.call(
            {
                auid:globalStore.userInfo.auid,
                targetAuid: globalStore.chatsContent.friendInfo.auid,
                alias:globalStore.chatsContent.friendInfo.alias
            }).then((resp) => {
            globalStore.showToast("修改成功")
        }).catch((e) => {
            globalStore.showApiErrorToast(e);
        })

    }

    onModifyRoomInfoPressOk(){
        EChatIMApis.updateRoom.call(globalStore.chatsContent.roomInfo).then((resp) => {
            globalStore.showToast("修改成功")
        }).catch((e) => {
            globalStore.showApiErrorToast(e);
        })
    }


    onAddRoomPressOk(){
        var friendToAddRoomList = globalStore.friendToAddRoomList.filter(function (v) {
            return !!v.select;
        });
        if(friendToAddRoomList.length === 0){
            globalStore.showToast("请选择群成员.");
            return;
        }
        var membersAuid = friendToAddRoomList.map(function(v){
            return v.auid;
        });
        var membersName = friendToAddRoomList.map(function(v){
            return v.name;
        });
        const form = new RoomAddForm();
        form.name = '讨论组(' + membersName.join() + ")";
        form.owner = globalStore.userInfo.auid;
        form.members = membersAuid;
        EChatIMApis.addRoom.call(form).then((resp) => {
            globalStore.showToast("操作成功");
            // globalStore.reloadData("room");
            NavigatorBar.pop(()=>{
                globalStore.requestRoomUpdate();
            });
        }).catch((e) => {
            globalStore.showApiErrorToast(e);
        })
    }



    //  --- WebNavigator 传值方案 ---//
    webNavigatorKey:string = '' // PAGE NAME + uuid
    webNavigatorKeyValue:any = {} //
}

export const globalStore = new ShareStore();


